package com.zw.stock_sell_storage.utils;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;

/**
 * 文件处理工具类
 */
public class FileUtils {
    //绝对路径
    private static String absolutePath="C:\\Users\\10745\\Desktop\\素材\\java";

    /**
     * 上传文件公共方法
     * @param file 文件对象
     * @param obj 当前控制器
     * @return 新的文件名称
     * @throws IOException
     */
    public static String uploadFile(MultipartFile file,Object obj) throws IOException {
        //获取文件上传时候的名称
        String sourceName = file.getOriginalFilename();
        //截取文件的后缀名
        String suffixName = sourceName.substring(sourceName.lastIndexOf("."));
        //组装文件在服务器存在的最终文件名
        //UUID 是一个随机的字符串，这个字符串重复的概率趋于0
        String newFileName = UUID.randomUUID() + suffixName;
        //获取文件存放服务器的路径
        //URL对象：获取路径得到当前static/images 的真实路径对象,
        URL url = obj.getClass().getClassLoader().getResource("static/images");
        //解码：服务器存在路径很多时候有些人喜欢中文命名，为了防止乱码需要设置
        String filePath = URLDecoder.decode(url.getFile(),"utf-8");
        //file源文件对象，方法中参数是目标文件对象
        file.transferTo(new File(filePath+"/"+newFileName));

        return newFileName;
    }

    /**
     * 上传文件到本地磁盘
     * @param file 文件对象
     * @return 返回新的文件名称
     * @throws IOException
     */
    public static String uploadFileAb(MultipartFile file) throws IOException {
        //获取文件上传时候的名称
        String fileName = file.getOriginalFilename();
        //截取文件的后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //得到新文件名
        String newFileName = UUID.randomUUID()+suffixName;
        file.transferTo(new File(absolutePath+newFileName));
        return newFileName;
    }

    /**
     * excel2007及以上版本
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static List<LinkedHashMap<String, Object>> xlsxImportExcel(InputStream file, Integer titleNo, Integer dataNo, Integer sheetNo) throws IOException {
        //log.info("excel2007及以上版本");
        // 读取流中的excel数据 这里用到的是poi中的XSSFWorkbook 用来处理xlsx(版本在2007以后的excel文件) HSSFWorkbook对象用来处理xls类型 版本为2003的文件
        XSSFWorkbook xwb = new XSSFWorkbook(file); //获取excel工作簿
        XSSFSheet xssfSheet = xwb.getSheetAt(sheetNo); //获取excel的sheet
        if (xssfSheet == null) {
            return null;
        }
        // 防止数据列错乱
        List<LinkedHashMap<String, Object>> mapList = new ArrayList<>();
        Row rowTitle = xssfSheet.getRow(titleNo);
        //循环获取excel每一行
        for (int rowNum = dataNo; rowNum < xssfSheet.getLastRowNum() + 1; rowNum++) {
            XSSFRow xssfRow = xssfSheet.getRow(rowNum);
            if (xssfRow == null) {
                continue;
            }
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            //循环获取excel每一行的每一列
            for (int cellNum = 0; cellNum < rowTitle.getLastCellNum(); cellNum++) {
                XSSFCell xssCell = xssfRow.getCell(cellNum);
                if (xssCell == null) {
                    // 防止单元格为空
                    map.put(rowTitle.getCell(cellNum).toString(), "");
                    continue;
                }
                try {
                    map.put(rowTitle.getCell(cellNum).toString(), getXSSFValue(xssCell));
                } catch (Exception e) {
                    //log.error("");
                }
            }
            mapList.add(map);  //将excel每一行的数据封装到map对象,并将map对象添加到list
        }
        return mapList;
    }

    /**
     * excel值处理
     *
     * @param hssfCell
     * @return
     */
    public static Object getXSSFValue(XSSFCell hssfCell) {
        Object result = null;
        int cellType = hssfCell.getCellType();
        switch (hssfCell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC: //数字
                if (HSSFDateUtil.isCellDateFormatted(hssfCell)) {
//                    需要对日期这一列进行设置样式，否则无法识别是日期类型还是数值类型
//                    默认不支持中文日期类型，需要设置成纯英语日期类型，不要包含年月日等汉字
//                    最好是使用这种格式 2019/10/10 0:00
                    SimpleDateFormat sdf = new SimpleDateFormat(
                            "yyyy-MM-dd HH:mm:ss");
                    result = sdf.format(HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue()));
                    break;
                }
                result = hssfCell.getNumericCellValue();
                break;
            case HSSFCell.CELL_TYPE_BOOLEAN: //Boolean
                result = hssfCell.getBooleanCellValue();
                break;
            case HSSFCell.CELL_TYPE_ERROR: //故障
                result = hssfCell.getErrorCellValue();
                break;
            case HSSFCell.CELL_TYPE_FORMULA: //公式
                result = hssfCell.getCellFormula();
                break;
            case HSSFCell.CELL_TYPE_BLANK:
                result = "";
                break;
            default: //字符串
                result = hssfCell.getStringCellValue();
        }
        return result;
    }

}
